#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <errno.h>
#include <string.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h> // for close
#define RECVBUFSIZE 1024

void *func(void *arg)//线程
{
 int new_fd,nbytes;
 char buffer[RECVBUFSIZE];
 int sin_size;
struct sockaddr_in client_addr;
struct sockaddr_in server_addr;
 new_fd = *((int *) arg);//客户端标识符
 free(arg);
 sin_size = sizeof(struct sockaddr);
 getsockname(new_fd, (struct sockaddr *)&client_addr, &sin_size);
//  printf("connect to server: %s:%d\n",inet_ntoa(client_addr.sin_addr),htons(client_addr.sin_port)); 
 while(1)
 {
  if((nbytes=recv(new_fd,buffer, RECVBUFSIZE,0))==-1)//当协议把数据接收完毕，recv函数就把new_fd客户端的接收缓冲中的数据copy到buffer中
  {
   fprintf(stderr,"Read Error:%s\n",strerror(errno));
   exit(1);
  }
  buffer[nbytes]='\0';
  bzero(&client_addr,sizeof(client_addr));
  getsockname(new_fd,(struct sockaddr *)&client_addr,&sin_size);
  bzero(&server_addr,sizeof(server_addr));
  getpeername(new_fd,(struct sockaddr *)&server_addr,&sin_size);
  printf("[server%s:%d to client%s:%d]server have sent:%s\n",inet_ntoa(server_addr.sin_addr),htons(server_addr.sin_port),inet_ntoa(client_addr.sin_addr),htons(client_addr.sin_port),buffer); 
  printf("input msg:\n");
 }
}

int main(int argc, char *argv[])
{
 int sockfd;
 char buffer[RECVBUFSIZE];
 struct sockaddr_in server_addr;
 struct sockaddr_in client_addr;
 struct hostent *host;
 int portnumber,nbytes; 
 pthread_t tid;
 int *pconnsocke = NULL;
 int ret;
 int sin_size;
 //检测参数个数
 if(argc!=3)
 {
  fprintf(stderr,"Usage:%s hostname portnumber\a\n",argv[0]);
  exit(1);
 }
 //argv2 存放的是端口号 ，读取该端口，转换成整型变量
 if((portnumber=atoi(argv[2]))<0)
 {
  fprintf(stderr,"Usage:%s hostname portnumber\a\n",argv[0]);
  exit(1);
 }
 //创建一个 客户端套接字
 if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
 {
  fprintf(stderr,"Socket Error:%s\a\n",strerror(errno));
  exit(1);
 }

 //填充结构体，ip和port必须是服务器的
 bzero(&server_addr,sizeof(server_addr));
 server_addr.sin_family=AF_INET;
 server_addr.sin_port=htons(portnumber);//argv[2]服务器端口号
 server_addr.sin_addr.s_addr = inet_addr(argv[1]);//argv【1】 是server ip地址
 /*向服务器发起连接*/ 
 if(connect(sockfd,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr))==-1)//connect获取sockfd对端(服务器)的地址server_addr
 {
  fprintf(stderr,"Connect Error:%s\a\n",strerror(errno));
  exit(1);
 }
 sin_size = sizeof(struct sockaddr); 
  printf("connect to server: %s:%d\n",inet_ntoa(server_addr.sin_addr),htons(server_addr.sin_port));
  getsockname(sockfd, (struct sockaddr *)&client_addr, &sin_size);
  printf("client_addr: %s:%d\n",inet_ntoa(client_addr.sin_addr),htons(client_addr.sin_port)); 
  getpeername(sockfd, (struct sockaddr *)&server_addr, &sin_size);
  printf("server_addr: %s:%d\n",inet_ntoa(server_addr.sin_addr),htons(server_addr.sin_port)); 
 //创建线程
 pconnsocke = (int *) malloc(sizeof(int));
 *pconnsocke = sockfd;
 
 ret = pthread_create(&tid, NULL, func, (void *) pconnsocke);//传参,pconnsocke指向sockfd描述符
 if (ret < 0) 
 {
  perror("pthread_create err");
  return -1;
 }
 printf("input msg:\n"); 
 while(1)
 {
 #if 1
  scanf("%s",buffer);
  if(send(sockfd,buffer,strlen(buffer),0)==-1)
  {
   fprintf(stderr,"Write Error:%s\n",strerror(errno));
   exit(1);
  }
  #endif
 }
 close(sockfd);
 exit(0);
}
